#include <iostream>
#include <vector>
#include <memory>
#include <stack>

// 接收者类
class Light {
public:
    void turnOn() {
        std::cout << "Light is on." << std::endl;
    }

    void turnOff() {
        std::cout << "Light is off." << std::endl;
    }
};

// 命令接口
class Command {
public:
    virtual ~Command() {}
    virtual void execute() = 0;
    virtual void undo() = 0;  // 添加一个undo方法用于撤销命令
};

// 具体命令类：开灯
class LightOnCommand : public Command {
private:
    Light& light;

public:
    LightOnCommand(Light& light) : light(light) {}

    void execute() override {
        light.turnOn();
    }

    void undo() override {
        light.turnOff();  // 撤销开灯命令即为关闭灯
    }
};

// 具体命令类：关灯
class LightOffCommand : public Command {
private:
    Light& light;

public:
    LightOffCommand(Light& light) : light(light) {}

    void execute() override {
        light.turnOff();
    }

    void undo() override {
        light.turnOn();  // 撤销关灯命令即为开启灯
    }
};

class RemoteControl {
private:
    std::vector<std::unique_ptr<Command>> onCommands;
    std::vector<std::unique_ptr<Command>> offCommands;
    std::stack<Command*> commandHistory;  // 用栈来记录命令历史

public:
    void setCommand(size_t slot, std::unique_ptr<Command> onCmd, std::unique_ptr<Command> offCmd) {
        if (slot >= onCommands.size()) {
            onCommands.resize(slot + 1);
            offCommands.resize(slot + 1);
        }
        onCommands[slot] = std::move(onCmd);
        offCommands[slot] = std::move(offCmd);
    }

    void pressOnButton(size_t slot) {
        if (slot < onCommands.size() && onCommands[slot] != nullptr) {
            onCommands[slot]->execute();
            commandHistory.push(onCommands[slot].get());  // 执行命令后将其压入历史栈
        }
    }

    void pressOffButton(size_t slot) {
        if (slot < offCommands.size() && offCommands[slot] != nullptr) {
            offCommands[slot]->execute();
            commandHistory.push(offCommands[slot].get());  // 执行命令后将其压入历史栈
        }
    }

    void pressUndoButton() {
        if (!commandHistory.empty()) {
            Command* lastCommand = commandHistory.top();
            lastCommand->undo();
            commandHistory.pop();  // 撤销命令后将其从历史栈中移除
        }
    }
};

int main() {
    Light livingRoomLight;
    RemoteControl remote;

    // 设置命令
    remote.setCommand(0, std::make_unique<LightOnCommand>(livingRoomLight), std::make_unique<LightOffCommand>(livingRoomLight));

    // 测试开灯命令
    std::cout << "Testing On Command:" << std::endl;
    remote.pressOnButton(0); // Light is on.
    std::cout << "Undoing On Command:" << std::endl;
    remote.pressUndoButton(); // Light is off.

    std::cout << std::endl; // 添加一个空行用于分隔输出

    // 测试关灯命令
    std::cout << "Testing Off Command:" << std::endl;
    remote.pressOffButton(0); // Light is off.
    std::cout << "Undoing Off Command:" << std::endl;
    remote.pressUndoButton(); // Light is on.

    return 0;
}
